package ru.spb.xmlreshelper.database;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import ru.spb.xmlreshelper.domain.CDTRecord;
import ru.spb.xmlreshelper.domain.DatabaseException;
import ru.spb.xmlreshelper.domain.ICdtService;

import javax.annotation.Nullable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.List;

/**
 * @author Nikita.Brazhnikov
 */
public class CDTManager implements ICdtService {

    private List<CDTRecord> cdtCache = null;

    @Override
    public List<CDTRecord> getCdts() throws DatabaseException {
        if (cdtCache == null) {
            updateCdts();
        }
        return cdtCache;
    }

    @Override
    public void updateCdts() throws DatabaseException {
        CDTDao dao = createDao();
        try {
            List<CDTRecord> loaded = dao.getCdts();
            if (cdtCache != null) {
                cdtCache.clear();
            } else
                cdtCache = Lists.newArrayListWithExpectedSize(loaded.size());
            cdtCache.addAll(loaded);
        } catch (SQLException e) {
            throw new DatabaseException(e);
        }
    }

    @Override
    public void updateXsl(Long cdtId, String pathToXsl) throws DatabaseException {
        CDTDao dao = createDao();
        try (InputStream is = new FileInputStream(pathToXsl)) {
            dao.updateXsl(cdtId, is);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        } catch (SQLException e) {
            throw new DatabaseException(e);
        }
    }

    @Override
    public void updateHtml(Long cdtId, String pathToHtml) throws DatabaseException {
        CDTDao dao = createDao();
        try (InputStream is = new FileInputStream(pathToHtml)) {
            dao.updateHtml(cdtId, is);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        } catch (SQLException e) {
            throw new DatabaseException(e);
        }
    }

    public String loadHtml(Long cdtId, String pathToSave) throws DatabaseException {
        CDTDao dao = createDao();
        try {
            File target = new File(pathToSave);
            if (target.exists()) {
                if (target.isDirectory()) {
                    //TODO
                }
            }
            final InputStream inputStream = dao.downloadHtml(cdtId);
            return target.getAbsolutePath();
        } catch (Exception e) {
            throw new DatabaseException(e);
        }
    }

    @Override
    public CDTRecord findCdt(final Long id) {
        if (cdtCache == null)
            updateCdts();
        final CDTRecord record = findCdtInternal(id);
        if (record != null)
            return record;
        updateCdts();
        return findCdtInternal(id);
    }

    private CDTRecord findCdtInternal(final Long id) {
        return Iterables.find(cdtCache, new Predicate<CDTRecord>() {
            @Override
            public boolean apply(@Nullable CDTRecord input) {
                return id.equals(input != null ? input.getCdt() : null);
            }
        }, null);
    }

    protected CDTDao createDao() {
        return new CDTDao(DatabaseManager.getInstance().getConnection());
    }
}
